package com.xoa.service.workflow.flowUtil;

import com.alibaba.fastjson.JSONArray;
import com.xoa.dao.WFE.WFEFormTypeMapper;
import com.xoa.dao.common.SysParaMapper;
import com.xoa.dao.document.DocumentModelMapper;
import com.xoa.dao.enclosure.AttachmentMapper;
import com.xoa.dao.work.WorkMapper;

import com.xoa.dao.workflow.FlowRunMapper;
import com.xoa.model.document.DocumentModel;
import com.xoa.model.document.DocumentModelWithBLOBs;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.workflow.FlowFormType;
import com.xoa.model.workflow.FlowRun;
import com.xoa.model.workflow.FlowRunLog;
import com.xoa.service.WFE.WFELog.WFELog;
import com.xoa.service.document.DocumentSerivce;
import com.xoa.service.enclosure.EnclosureService;
import com.xoa.service.rms.impl.RmsFileServiceImpl;
import com.xoa.service.syspara.impl.SysParaNotifyServiceImpl;
import com.xoa.util.*;
import com.xoa.util.common.L;
import com.xoa.util.common.StringUtils;
import com.xoa.util.netdisk.ZipUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by zhanghangning on 2019/3/28.
 */
@Service
public class FlowUtilService {

    @Autowired
    private WFEFormTypeMapper wfeFormTypeMapper;

    @Autowired
    private WFELog wfeLog;

    @Autowired
    private WorkMapper workMapper;

    @Autowired
    private AttachmentMapper attachmentMapper;

    @Autowired
    private RmsFileServiceImpl rmsFileService;

    @Autowired
    protected EnclosureService enclosureService;


    @Autowired
    private FlowRunMapper flowRunMapper;

    @Autowired
    DocumentSerivce documentSerivce;

    @Resource
    private DocumentModelMapper documentModelMapper;

    @Resource
    private SysParaMapper sysParaMapper;

    @Resource
    private SysParaNotifyServiceImpl sysParaNotifyService;


    /**
     * 创建作者:  张航宁
     * 创建日期:  2019/3/28
     * 方法介绍:  工作流表单导出为PDF文件
     * 参数说明:
     *
     * @return
     */
    public ToJson<Attachment> htmlFormTOPDF(HttpServletRequest request, HttpServletResponse response, Integer runId, String module, String htmlContent) {
        ToJson<Attachment> json = new ToJson<Attachment>();

        FlowRun flowRun = flowRunMapper.selectByRunId(runId);
        String idname = "";
        if (flowRun != null) {
            // 特殊处理一下runName
            if (!StringUtils.checkNull(flowRun.getRunName())) {
                flowRun.setRunName(flowRun.getRunName().replace(":", "_").replace("|", "_").replace("/", "_").replace("\\", "_"));
            }
            // 设置pdf默认最大宽度
            String widthStr = request.getParameter("width");
            String heightStr = request.getParameter("height");
            Integer maxWidth = Integer.parseInt(widthStr == null ? "1066" : widthStr.contains(".") ? widthStr.substring(0, widthStr.indexOf(".")) : widthStr);
            Integer maxHeight = Integer.parseInt(heightStr == null ? "1886" : heightStr.contains(".") ? heightStr.substring(0, heightStr.indexOf(".")) : heightStr);

            // 判断前端是否传递了表单的html信息
            if (StringUtils.checkNull(htmlContent)) {

                // 获取无数据的表单信息
                FlowFormType flowFormType = null;
                List<FlowFormType> frombyFlowId = wfeFormTypeMapper.getFrombyFlowId(flowRun.getFlowId());
                if (frombyFlowId != null && frombyFlowId.size() > 0) {
                    flowFormType = frombyFlowId.get(0);
                }

                // 数据查询参数map
                Map<String, Object> parameterMap = new HashMap<String, Object>();
                parameterMap.put("tableName", "flow_data_" + flowRun.getFlowId());
                parameterMap.put("runId", runId);
                // 查询表单数据
                Map<String, Object> dataMap = workMapper.select(parameterMap);

                htmlContent = flowFormType.getPrintModel();
                // 通过Jsoup插件解析成document对象（非公文的document对象）
                Document parse = Jsoup.parse(htmlContent);

                if (dataMap == null)
                    return json;

                if (parse.getElementsByClass("td-min-height") != null) {
                    String style1 = parse.getElementsByClass("td-min-height").attr("style");

                    if (!StringUtils.checkNull(style1) && style1.indexOf("width") != -1) {
                        String[] split = style1.split(";");
                        for (int i = 0, length = split.length; i < length; i++) {
                            String s = split[i];
                            if (s.indexOf("width") != -1) {
                                String width = s.replace("width:", "").replace("px", "");
                                if (!"undefined".equals(width.trim()))
                                    maxWidth = Integer.valueOf(width.trim());
                            }
                        }
                    }
                }


                Iterator<Map.Entry<String, Object>> iterator = dataMap.entrySet().iterator();

                // 循环获取到key和value 并赋值到元素上
                while (iterator.hasNext()) {
                    Map.Entry<String, Object> entry = iterator.next();
                    Element element = parse.getElementById(String.valueOf(entry.getKey()).toUpperCase());
                    // 赋值操作
                    if (element != null) {

                        element.val(String.valueOf(entry.getValue()));
                        element.attr("disabled", "disabled");

                        String style = element.attr("style");

                        // 图片控件特殊处理
                        if (element.className().indexOf("imgupload") > 0) {
                            element.before("<span class='preview' style='" + style + "overflow: hidden;'><img src='" + String.valueOf(entry.getValue()) + "' ></span>").
                                    attr("style", style + "display: none");
                            //附件特殊处理 只显示名字
                        } else if (element.className().indexOf("upload") > 0) {
                            element.before("<span class='preview' style='" + style + "overflow: hidden;'>" + getAttachmentNames((String) entry.getValue()) + "</span>").
                                    attr("style", style + "display: none");
                            // 手写特殊处理
                        } else if (element.attr("data-type").contains("writesign")) {
                            element.before("<span class='preview' style='" + style + "overflow: hidden;'><img style='width:65px;' src='" + String.valueOf(entry.getValue()) + "' ></span>").
                                    attr("style", style + "display: none");
                            // 宏控件特殊处理
                        } else if (element.attr("data-type").contains("macros") && element.attr("datafld").contains("SYS_USERNAME")) {
                            if (!StringUtils.checkNull(String.valueOf(entry.getValue())) && String.valueOf(entry.getValue()).contains("xs?")) {
                                element.before("<span class='preview' style='" + style + "overflow: hidden;'><img style='width:65px;' src='" + String.valueOf(entry.getValue()) + "' ></span>").
                                        attr("style", style + "display: none");
                            } else {
                                element.before("<span class='preview' style='" + style + "overflow: hidden;'>" + String.valueOf(entry.getValue()).replace("\n", "<br>") + "</span>").
                                        attr("style", style + "display: none");
                            }
                            // 普通表单默认显示
                        } else {
                            element.before("<span class='preview' style='" + style + "overflow: hidden;'>" + String.valueOf(entry.getValue()).replace("\n", "<br>") + "</span>").
                                    attr("style", style + "display: none");
                        }
                    }
                }

                // 拼接html代码
                htmlContent = "<div class=\"cont_form\" id=\"a2\"><div>" + parse.outerHtml() + "</div></div>";

            }

            // 处理图片 设置图片路径地址为绝对路径地址 导出PDF的图片需要用绝对路径地址
            Document parse = Jsoup.parse("<div id='all_content'>" + htmlContent + "</div>");
            Elements imgs = parse.getElementsByTag("img");
            for (Element img : imgs) {
                String src = img.attr("src");
                if (src.contains("xs?")) {
                    Attachment attachment = attachmentMapper.findByAttachId(Integer.parseInt(getAttachParamValue(src, "AID")));
                    if (attachment != null) {
                        // 获取xoa路径地址
                        StringBuilder imgRealPath = FileUploadUtil.getUploadHead();
                        ;
                        // 拼接相对路径
                        imgRealPath.append(System.getProperty("file.separator"))
                                .append("xoa" + (String) request.getSession().getAttribute("loginDateSouse")).append(System.getProperty("file.separator"))
                                .append(getAttachParamValue(src, "MODULE")).append(System.getProperty("file.separator"))
                                .append(attachment.getYm()).append(System.getProperty("file.separator"))
                                .append(attachment.getAttachId()).append(".").append(attachment.getAttachName());
                        // 替换图片路径为相对路径
                        img.attr("src", imgRealPath.toString());
                    }
                }
            }

            htmlContent = parse.toString();


            // 文件存储头
            StringBuilder uploadHead = FileUploadUtil.getUploadHead();

            // 当前年月
            String ym = new SimpleDateFormat("yyMM").format(new Date());

            // 组织
            String company = "xoa" + (String) request.getSession().getAttribute("loginDateSouse");

            // 时间戳数字串
            String attachID = String.valueOf(Math.abs((int) System.currentTimeMillis()));

            // 文件存储路径
            StringBuilder filePath = uploadHead.append(System.getProperty("file.separator")).
                    append(company).append(System.getProperty("file.separator")).
                    append("workflow").append(System.getProperty("file.separator")).
                    append(ym).append(System.getProperty("file.separator"));


            // 生成文件目录
            new File(filePath.toString()).mkdirs();

            //判断是否需要转为base64编码开始--------------------------------------------------------

            String flowRunNameBase64 = "";
            String runName = runId + " " + flowRun.getRunName();
            String osName = System.getProperty("os.name");
            int codeLength = 0;
            try {
                codeLength = runName.getBytes("UTF-8").length;
                if (codeLength>230&&osName.toLowerCase().startsWith("linu")) {//
                    String s = (new BASE64Encoder()).encodeBuffer(runName.getBytes(StandardCharsets.UTF_8));
                    String regEx = ("[\\s\\\\/:\\*\\?\\\"<>\\|]");
                    flowRunNameBase64 = (Pattern.compile(regEx).matcher(s).replaceAll("").trim().substring(0,100));
                }
            } catch (Exception e) {
            }

            //判断是否需要转为base64编码结束--------------------------------------------------------
            // 获得原始文件名
            String htmlFileName ="";
            if(!StringUtils.checkNull(flowRunNameBase64)){
                htmlFileName=String.valueOf(flowRunNameBase64+".html");
            }else{
                htmlFileName=String.valueOf(runId +" "+ flowRun.getRunName())+".html";
            }
            String newFileName = attachID + "." + htmlFileName;

            // 生成文件
            String htmlFilePath = uploadHead.toString() + newFileName;
            File f = new File(htmlFilePath);
            OutputStreamWriter pw =null;
            try {
                if (!f.exists()) {
                    f.createNewFile();
                }
                 pw = new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8);

                // 特殊处理htmlContent
                htmlContent = htmlContent.replace("<>", "<div style='display:none'>");
                htmlContent = htmlContent.replace("</>", "</div>");
                htmlContent = htmlContent.replace("&lt;&gt;", "");
                // 特殊处理引入的样式
                // 获取webRoot路径
                String webRootPath = request.getSession().getServletContext().getRealPath("/");
                String linkStyle =
                        "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/m_reset.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/new_work.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/bootstrap.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/laydate.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/handle.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/dept/roleAuthorization.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/layer/skin/default/layer.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/laydate/need/laydate.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/laydate/skins/default/laydate.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/kinggrid/dialog/artDialog/ui-dialog.css\">\n" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/kinggrid/core/kinggrid.plus.css\">" +
                                "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/workFormPreView.css\">";

                linkStyle = linkStyle.replace("ui/lib", webRootPath + "ui/lib").replace("ui/css", webRootPath + "ui/css");

                // 写入文件
                pw.write("<html><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">");
                pw.write(linkStyle);
                pw.write("</head>");
                pw.write("<body>");
                pw.write(htmlContent);
                pw.write("</body></html>");
                pw.close();

                //复制表单html文件
                Attachment attachment = new Attachment();
                attachment.setAttachId(attachID);//
                attachment.setModule((byte) 2);
                attachment.setAttachFile(runId + " " + flowRun.getRunName() + ".html");
                attachment.setAttachName(runId + " " + flowRun.getRunName() + ".html");
                attachment.setYm(ym);
                attachment.setAttachSign(new Long(0));
                attachment.setDelFlag((byte) 0);
                attachment.setPosition((byte) 2);
                attachment.setIsImage((byte) 0);
                //attachment.setSize();
                attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                // 把附件信息存储进数据库中
                attachmentMapper.insertSelective(attachment);

                List<Attachment> attachments = new ArrayList<Attachment>();
                attachments.add(attachment);
                Object[] o = FileUploadUtil.reAttachment(attachments);
                idname = o[0].toString() + "%" + o[1].toString() + "%";
            } catch (Exception e) {
                e.printStackTrace();
                L.e(e.getMessage());
            }finally {
                try {
                    if (pw != null) {
                        pw.close();
                    }
                }catch (Exception e){

                }
            }
            try {
                if(codeLength>230&&osName.toLowerCase().startsWith("linu")){//
                    String s = (new BASE64Encoder()).encodeBuffer(runName.getBytes(StandardCharsets.UTF_8));
                    String regEx=("[\\s\\\\/:\\*\\?\\\"<>\\|]");
                    flowRunNameBase64=(Pattern.compile(regEx).matcher(s).replaceAll("").trim().substring(0,100));
                }
            } catch (Exception e) {

            }
            // pdf文件名称
            String pdfFileName ="";
            if(!StringUtils.checkNull(flowRunNameBase64)){
                pdfFileName=String.valueOf(Math.abs((int) System.currentTimeMillis())) + "." + flowRunNameBase64+".pdf";
            }else{
                pdfFileName=String.valueOf(Math.abs((int) System.currentTimeMillis())) + "." + runId +" "+ flowRun.getRunName()+".pdf";
            }

            // pdf文件路径
            String pdfFilePath = filePath.append(pdfFileName).toString();

            // 生成PDF
            HtmlToPdfUtil.htmlToPDF(maxWidth, maxHeight, htmlFilePath, pdfFilePath, request);

            File pdfFile = new File(pdfFilePath);

            // 判断是否存在pdf文件
            if (pdfFile.exists()) {

                //获得模块id
                byte mid = 0;
                for (ModuleEnum em : ModuleEnum.values()) {
                    if (em.getName().equals(module.trim())) {
                        mid = (byte) em.getIndex();
                    }
                }
                //获取pdf的attid
                String id = "";
                try {
                    id = pdfFileName.split("\\.")[0];
                } catch (Exception e) {
                    e.getStackTrace();
                    e.printStackTrace();
                }

                // 保存进数据库
                Attachment attachment = new Attachment();
                attachment.setAttachId(id);
                attachment.setModule(mid);
                attachment.setAttachFile(runId + " " + flowRun.getRunName() + ".pdf");
                attachment.setAttachName(runId + " " + flowRun.getRunName() + ".pdf");
                attachment.setYm(ym);
                attachment.setAttachSign(new Long(0));
                attachment.setDelFlag((byte) 0);
                attachment.setPosition((byte) 2);
                attachment.setIsImage((byte) 0);
                attachment.setSize(Convert.convertFileSize(pdfFile.length()));
                attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                // 把附件信息存储进数据库中
                attachmentMapper.insertSelective(attachment);


                String attUrl = "AID=" + attachment.getAid() + "&" + "MODULE=" + module + "&" + "COMPANY=" + company + "&" + "YM=" + attachment.getYm() + "&" + "ATTACHMENT_ID=" + attachment.getAttachId() + "&" +
                        "ATTACHMENT_NAME=" + attachment.getAttachName() + "&" + "FILESIZE=" + attachment.getFileSize();

                attachment.setAttUrl(attUrl);

                json.setObj1(idname);
                json.setObject(attachment);
                json.setFlag(0);
                json.setMsg("ok");

                //添加导出日志
                HttpServletRequest request1 = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                FlowRunLog flowRunLog = wfeLog.getFlowRunLogByRequest(request1);
                flowRunLog.setRunId(runId);
                flowRunLog.setType(Constant.TYPE6);
                wfeLog.addFlowRunLog(flowRunLog);

            }

        }

        return json;

    }

    /**
     * 创建者: 张航宁
     * 创建日期：2019/02/11
     * 方法介绍: 工作流附件转公告接口
     */
    public ToJson<Attachment> flowAttach2Other(HttpServletRequest request, Integer runId, String module) {

        ToJson<Attachment> json = new ToJson<Attachment>();

        // 组织
        String company = "xoa" + (String) request.getSession().getAttribute("loginDateSouse");

        // 根据runid获取工作流流程信息
        FlowRun flowRun = flowRunMapper.selectByRunId(runId);

        DocumentModel documentModel = documentModelMapper.checkRunId(runId);


        // 判断是否有附件
        if (flowRun==null||StringUtils.checkNull(flowRun.getAttachmentId()) || StringUtils.checkNull(flowRun.getAttachmentName())) {
            if(documentModel==null||StringUtils.checkNull(documentModel.getMainFile())||StringUtils.checkNull(documentModel.getMainFile())){
                json.setMsg("没有附件");
                json.setFlag(1);
                return json;
            }
        }

        // 创建存储新附件的list
        List<Attachment> newAttachmentList = new ArrayList<Attachment>();

        // 获取附件信息
        List<Attachment> flowAttachmentList = GetAttachmentListUtil.returnAttachment(flowRun.getAttachmentName(), flowRun.getAttachmentId(), company, "workflow");
        String oldModule = "workflow";

        try{
            copyFiles(module, company, newAttachmentList, flowAttachmentList, oldModule);
        }catch (Exception e){
            e.printStackTrace();
            json.setFlag(1);
            json.setMsg("err:"+e.getMessage());
        }

        // 获取公文正文附件
        if(documentModel!=null&&!StringUtils.checkNull(documentModel.getMainFile())&&!StringUtils.checkNull(documentModel.getMainFileName())){
            List<Attachment> document = GetAttachmentListUtil.returnAttachment(documentModel.getMainFileName(), documentModel.getMainFile(), company, "document");
            try{
                oldModule = "document";
                copyFiles(module, company, newAttachmentList, document, oldModule);
            }catch (Exception e){
                e.printStackTrace();
                json.setFlag(1);
                json.setMsg("err:"+e.getMessage());
            }
        }

        // 获取公文正文版式文件附件
        if(documentModel!=null&&!StringUtils.checkNull(documentModel.getMainAipFile())&&!StringUtils.checkNull(documentModel.getMainAipFileName())){
            List<Attachment> document = GetAttachmentListUtil.returnAttachment(documentModel.getMainAipFileName(), documentModel.getMainAipFile(), company, "document");
            try{
                oldModule = "document";
                copyFiles(module, company, newAttachmentList, document, oldModule);
            }catch (Exception e){
                e.printStackTrace();
                json.setFlag(1);
                json.setMsg("err:"+e.getMessage());
            }
        }

        json.setObj(newAttachmentList);
        json.setFlag(0);
        json.setMsg("ok");

        return json;
    }

    private void copyFiles(String module, String company, List<Attachment> newAttachmentList, List<Attachment> flowAttachmentList, String oldModule) throws IOException {
        // 循环遍历拷贝
        for (int i = 0, size = flowAttachmentList.size(); i < size; i++) {

            Attachment flowAttachment = flowAttachmentList.get(i);

            // 文件存储头
            StringBuilder uploadHead = FileUploadUtil.getUploadHead();

            // 当前年月
            String ym = new SimpleDateFormat("yyMM").format(new Date());

            // 时间戳数字串
            String attachID = String.valueOf(Math.abs((int) System.currentTimeMillis()));

            // 文件存储路径
            StringBuilder flowFilePath = uploadHead.append(System.getProperty("file.separator")).
                    append(company).append(System.getProperty("file.separator")).
                    append(oldModule).append(System.getProperty("file.separator")).
                    append(flowAttachment.getYm()).append(System.getProperty("file.separator"));

            StringBuilder notifyFilePath = new StringBuilder(flowFilePath.toString().replace(oldModule, module.trim()));


            //获得模块id
            byte mid = 0;
            for (ModuleEnum em : ModuleEnum.values()) {
                if (em.getName().equals(module.trim())) {
                    mid = (byte) em.getIndex();
                }
            }

            File flowFile = new File(flowFilePath.append(flowAttachment.getAttachId()).append(".").append(flowAttachment.getAttachName()).toString());

            if (!flowFile.exists()) {
                continue;
            }

            File notifyFile = new File(notifyFilePath.append(attachID).append(".").append(flowAttachment.getAttachName()).toString());

            FileUploadUtil.copyFileUsingFileChannels(flowFile, notifyFile);


            // 保存进数据库
            Attachment attachment = new Attachment();
            attachment.setAttachId(attachID);
            attachment.setModule(mid);
            attachment.setAttachFile(flowAttachment.getAttachFile());
            attachment.setAttachName(flowAttachment.getAttachName());
            attachment.setYm(ym);
            attachment.setAttachSign(new Long(0));
            attachment.setDelFlag((byte) 0);
            attachment.setPosition((byte) 2);
            attachment.setIsImage((byte) 0);
            attachment.setSize(Convert.convertFileSize(flowFile.length()));
            attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            // 把附件信息存储进数据库中
            attachmentMapper.insertSelective(attachment);

            String attUrl = "AID=" + attachment.getAid() + "&MODULE="+ module + "&COMPANY=" + company + "&YM=" + attachment.getYm() + "&ATTACHMENT_ID=" + attachment.getAttachId() +
                    "&ATTACHMENT_NAME=" + attachment.getAttachName() + "&FILESIZE=" + attachment.getFileSize();

            attachment.setAttUrl(attUrl);

            newAttachmentList.add(attachment);
        }
    }


    /**
     * @接口说明: 工作流附件转存压缩附件功能
     * @日期: 2020/4/16
     * @作者: 张航宁
     */
    public ToJson<Attachment> saveToFile(HttpServletRequest request, Integer runId, String module, String fileName, String htmlContent, Integer sortId, String formAttachment) {
        ToJson<Attachment> json = new ToJson<>();
        FlowRun flowRun = flowRunMapper.selectByRunId(runId);

        if (StringUtils.checkNull(module)) {
            module = "file_folder";
        }
        // 获取流程中的附件信息
        String attachmentName = flowRun.getAttachmentName();
        String attachmentId = flowRun.getAttachmentId();

        String[] formAttachments = formAttachment.split("\\*");

        // 定义存储附件名称和附件id的变量
        StringBuilder formAttachmentNames = new StringBuilder();
        StringBuilder formAttachmentIds = new StringBuilder();
        // 循环遍历表单中的附件
        for (int i = 0, size = formAttachments.length; i < size; i++) {
            String s = formAttachments[i];
            String[] split = s.split(",");
            for (int j = 0, length = split.length; j < length; j++) {
                String s1 = split[j];
                String[] split2 = s1.split("&");
                // 定义存储变量
                String aid = "";
                String ym = "";
                String attachId = "";
                String attachName = "";
                for (int k = 0, length2 = split2.length; k < length2; k++) {
                    String[] split3 = split2[k].split("=");
                    if (split3.length > 1) {
                        if (split3[0].toUpperCase().equals("AID")) {
                            aid = split3[1];
                        } else if (split3[0].toUpperCase().equals("YM")) {
                            ym = split3[1];
                        } else if (split3[0].toUpperCase().equals("ATTACHMENT_ID")) {
                            attachId = split3[1];
                        } else if (split3[0].toUpperCase().equals("ATTACHMENT_NAME")) {
                            attachName = split3[1];
                        }
                    }
                }
                if (!StringUtils.checkNull(aid)) {
                    formAttachmentIds.append(aid).append("@").append(ym).append("_").append(attachId).append(",");
                    formAttachmentNames.append(attachName).append(",");
                }
            }
        }


        // 获取上传路径
        StringBuilder uploadHead = FileUploadUtil.getUploadHead();

        // 组织
        String company = "xoa" + (String) request.getSession().getAttribute("loginDateSouse");

        // 获取工作流flow_run中的附件信息 进行压缩打包
        List<Attachment> attachmentList = GetAttachmentListUtil.returnAttachment(attachmentName, attachmentId, company, "workflow");
        // 获取表单中的附件信息数组
        if (!StringUtils.checkNull(formAttachmentIds.toString()) && !StringUtils.checkNull(formAttachmentNames.toString())) {
            List<Attachment> attachmentList1 = GetAttachmentListUtil.returnAttachment(formAttachmentNames.toString(), formAttachmentIds.toString(), company, "workflow");
            attachmentList.addAll(attachmentList1);
        }
        // 要压缩的文件集合
        List<File> files = new ArrayList<File>();
        // 循环添加
        for (int i = 0, length = attachmentList.size(); i < length; i++) {
            Attachment attachment = attachmentList.get(i);
            StringBuilder flowFilePath = new StringBuilder(uploadHead.toString());
            flowFilePath.append(System.getProperty("file.separator")).
                    append(company).append(System.getProperty("file.separator")).
                    append("workflow").append(System.getProperty("file.separator")).append(attachment.getYm()).
                    append(System.getProperty("file.separator")).append(attachment.getAttachId()).append(".").append(attachment.getAttachName());
            File file = new File(flowFilePath.toString());
            if (file.exists()) {
                files.add(file);
            }
        }

        // 当前年月
        String ym = new SimpleDateFormat("yyMM").format(new Date());
        // 表单文件存储路径
        StringBuilder htmlFilePathBd = uploadHead;
        htmlFilePathBd.append(System.getProperty("file.separator")).
                append(System.getProperty("file.separator")).
                append(company).append(System.getProperty("file.separator")).
                append(module).append(System.getProperty("file.separator")).append(ym);

        // 表单文件路径地址
        String htmlFilePath = htmlFilePathBd.toString();
        if (!new File(htmlFilePath).exists()) {
            new File(htmlFilePath).mkdirs();
        }
        File formHtmlFile = null;
        try {
            //替换特殊符号文件名
            String[] strs = new String[]{":", "\\", "/", "*", "?", "\"", "<", ">", "|"};
            for (String str : strs) {
                fileName = fileName.replace(str, " ");
            }
            formHtmlFile = File.createTempFile(fileName, ".html");
            // 表单内容写入到表单文件中
            String webRootPath = request.getSession().getServletContext().getRealPath("/");
            String linkStyle =
                    "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/m_reset.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/new_work.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/bootstrap.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/laydate.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/handle.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/dept/roleAuthorization.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/layer/skin/default/layer.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/laydate/need/laydate.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/laydate/skins/default/laydate.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/kinggrid/dialog/artDialog/ui-dialog.css\">\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/lib/kinggrid/core/kinggrid.plus.css\">" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"ui/css/workflow/work/workFormPreView.css\">";

            linkStyle = linkStyle.replace("ui/lib", webRootPath + "ui/lib").replace("ui/css", webRootPath + "ui/css");

            OutputStreamWriter pw = new OutputStreamWriter(new FileOutputStream(formHtmlFile), "UTF-8");
            pw.write("<html><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"></head>");
            pw.write(linkStyle);
            pw.write("<body>");
            pw.write(htmlContent);
            pw.write("</body></html>");
            pw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获得模块id
        byte mid = 0;
        for (ModuleEnum em : ModuleEnum.values()) {
            if (em.getName().equals(module)) {
                mid = (byte) em.getIndex();
            }
        }
        // 把表单添加到集合中
        files.add(formHtmlFile);
        //不压缩直接存附件
        List<Attachment> attachmentList1 = new ArrayList<>();
        for (File file : files) {
            String oldFileName = file.getName();
            //html 临时文件去掉 自动生成的时间戳
            if (oldFileName.startsWith(fileName) && oldFileName.endsWith(".html")) {
                oldFileName = fileName + ".html";
            } else {
                //去掉文件旧的时间戳,因为所有的附件都是转存过来的 所以都存在时间戳
                oldFileName = oldFileName.substring(oldFileName.indexOf(".") + 1);
            }
            byte[] buf = new byte[1024];
            int attachIDs = Math.abs((int) System.currentTimeMillis());
            String FName = attachIDs + "." + oldFileName;
            String FilePath = htmlFilePath + System.getProperty("file.separator") + FName;
            try (FileOutputStream out = new FileOutputStream(new File(FilePath)); FileInputStream in = new FileInputStream(file)) {
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            File zipFile = new File(FilePath);
            if (zipFile.exists()) {
                Attachment attachment = new Attachment();
                attachment.setAttachId(String.valueOf(attachIDs));
                attachment.setModule(mid);
                attachment.setAttachFile(oldFileName);
                attachment.setAttachName(oldFileName);
                attachment.setYm(ym);
                attachment.setAttachSign(new Long(0));
                attachment.setDelFlag((byte) 0);
                attachment.setPosition((byte) 2);
                attachment.setSize(Convert.convertFileSize(file.length()));
                attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                attachmentMapper.insertSelective(attachment);
                attachmentList1.add(attachment);
            }
        }

        StringBuilder attachmentIds = new StringBuilder();
        StringBuilder attachmentNames = new StringBuilder();
        attachmentList1.forEach(attachment -> {
            attachmentIds.append(attachment.getAid() + "@" + attachment.getYm() + "_" + attachment.getAttachId() + ",");
            attachmentNames.append(attachment.getAttachName() + "*");
        });


        //============================================================================================
        // 生成压缩包地址
//        String zipPath = filePath.replace(fileName + ".html", fileName + ".zip");
//        /*上分割线*/
//        // TODO 临时：为确保生成zip文件修改路径
//        // TODO 本地和服务器上的上传路径不同...
//        // 注：ZipUtils.zipFiles使用绝对路径
//        // 获得盘符
//        if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
//            String diskSymbol = new File("").getAbsolutePath().substring(0, 2);
//            // 路径中不包含：认为是相对路径
//            if (!zipPath.contains(":")) {
//                zipPath = diskSymbol + zipPath;
//            }
//        }
//        /*下分割线*/
//        ZipUtils.zipFiles(files, zipPath);
//        // 获取zipFile
//        File zipFile = new File(zipPath);
//        // 如果文件不存在
//        if (zipFile.exists()) {
//            fileName = fileName + ".zip";
//            // 保存进数据库
//            Attachment attachment = new Attachment();
//            attachment.setAttachId(String.valueOf(attachID));
//            attachment.setModule(mid);
//            attachment.setAttachFile(fileName);
//            attachment.setAttachName(fileName);
//            attachment.setYm(ym);
//            attachment.setAttachSign(new Long(0));
//            attachment.setDelFlag((byte) 0);
//            attachment.setPosition((byte) 2);
//            attachment.setIsImage((byte) 0);
//            attachment.setFileSize(String.valueOf(formHtmlFile.length()));
//            attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//            attachmentMapper.insertSelective(attachment);
//        }
        json.setFlag(0);
        json.setMsg("0");
        return json;
    }

    // 附件串拆分获取名称工具
    public String getAttachmentNames(String attachmentStr) {

        if (StringUtils.checkNull(attachmentStr))
            return "";

        StringBuilder stringBuilder = new StringBuilder();

        String[] attachmentItem = attachmentStr.split("\\*");

        for (int i = 0, length = attachmentItem.length; i < length; i++) {
            String s = attachmentItem[i];
            String[] split = s.split("&");
            for (int j = 0, length2 = split.length; j < length2; j++) {
                if (split[j].indexOf("ATTACHMENT_NAME=") != -1)
                    stringBuilder.append(split[j].replace("ATTACHMENT_NAME=", "")).append("<br/>");
            }
        }

        return stringBuilder.toString();
    }

    // 获取附件串中指定参数的值
    public String getAttachParamValue(String attachmentStr, String paramName) {

        if (StringUtils.checkNull(attachmentStr))
            return "";

        // 特殊处理手写上传的图片
        if (attachmentStr.contains("|"))
            attachmentStr = attachmentStr.split("\\|")[0];

        attachmentStr = attachmentStr.replace("/xs?", "");
        attachmentStr = attachmentStr.replace("/download?", "");


        String[] attachmentItem = attachmentStr.split("\\*");

        for (int i = 0, length = attachmentItem.length; i < length; i++) {
            String s = attachmentItem[i];
            String[] split = s.split("&");
            for (int j = 0, length2 = split.length; j < length2; j++) {
                if (split[j].indexOf(paramName + "=") != -1)
                    return split[j].replace(paramName + "=", "");
            }
        }

        return "";
    }


    public ToJson<Attachment> flowAttachDocument(HttpServletRequest request, Integer runId, String module) {
        ToJson<Attachment> json = new ToJson<>();
        String sqlType = "xoa" + (String) request.getSession().getAttribute("loginDateSouse");
        FileUploadUtil fileUploadUtil = new FileUploadUtil();
        // 获取父公文实体类
        DocumentModel fathDocument = documentSerivce.checkRunId(runId);
        // 设置内部分发标题
        json.setObject(fathDocument.getTitle());
        DocumentModelWithBLOBs fathDocuments = documentModelMapper.checkRunIds(runId);
        List<Attachment> fathAttach = new ArrayList<Attachment>();//先设置空的正文
        //获取父公文的正文
        if (StringUtils.checkNull(fathDocument.getMainAipFile())) {//判断api为空
            fathAttach = GetAttachmentListUtil.returnAttachment(fathDocument.getMainFileName(), fathDocument.getMainFile(), sqlType, "document");
        } else {
            fathAttach = GetAttachmentListUtil.returnAttachment(fathDocument.getMainAipFileName(), fathDocument.getMainAipFile(), sqlType, "document");
        }
        //复制文件
        List<Attachment> sonAttach = fileUploadUtil.copyFiles(fathAttach, sqlType, "document", module);
        for (Attachment attachment : sonAttach) {
            enclosureService.saveAttachment(attachment);
        }
        Object[] o = FileUploadUtil.reAttachment(sonAttach);
        DocumentModelWithBLOBs document = new DocumentModelWithBLOBs();
        if (StringUtils.checkNull(fathDocument.getMainAipFile())) {//pdf为空  复制word
            document.setMainFile(o[0].toString().split(",")[0]);
            document.setMainFileName(o[1].toString().split("\\*")[0]);
        } else {
            document.setMainAipFile(o[0].toString().split(",")[0]);
            document.setMainAipFileName(o[1].toString().split("\\*")[0]);
        }
        List<Attachment> attachmentList = null;
        if (!StringUtils.checkNull(document.getMainAipFile())) { //pdf不为空
            attachmentList = GetAttachmentListUtil.returnAttachment(document.getMainAipFileName(), document.getMainAipFile(), sqlType, module);
        } else {
            attachmentList = GetAttachmentListUtil.returnAttachment(document.getMainFileName(), document.getMainFile(), sqlType, module);
        }

        json.setObj(attachmentList);
        String sysPara = null;
        try {
            sysPara = sysParaMapper.querySysPara("MYPROJECT").getParaValue();//防止有的产品没有myproject这个值
        } catch (Exception e) {

        }
        if (!StringUtils.checkNull(sysPara) && "powerchina".equals(sysPara)) {  //内部分发
            ToJson<Object> notifyTypeList = sysParaNotifyService.getNotifyTypeList(request);
            List<Object> obj = notifyTypeList.getObj();
        }
        json.setObj1("04");
        json.setFlag(0);
        return json;
    }

    public ToJson<Attachment> flowAttachDocOrPdf(HttpServletRequest request, Integer runId, String module, Integer type) {
        ToJson<Attachment> json = new ToJson<>();
        String sqlType = "xoa" + (String) request.getSession().getAttribute("loginDateSouse");
        FileUploadUtil fileUploadUtil = new FileUploadUtil();
        //获取父公文实体类
        DocumentModel fathDocument = documentSerivce.checkRunId(runId);
        DocumentModelWithBLOBs fathDocuments = documentModelMapper.checkRunIds(runId);
        List<Attachment> fathAttach = new ArrayList<Attachment>();//先设置空的正文
        //获取父公文的正文
        if (1 == type) {// doc
            fathAttach = GetAttachmentListUtil.returnAttachment(fathDocument.getMainFileName(), fathDocument.getMainFile(), sqlType, "document");
        } else if (2 == type) {// pdf
            fathAttach = GetAttachmentListUtil.returnAttachment(fathDocument.getMainAipFileName(), fathDocument.getMainAipFile(), sqlType, "document");
        }
        //复制文件
        List<Attachment> sonAttach = fileUploadUtil.copyFiles(fathAttach, sqlType, "document", module);
        for (Attachment attachment : sonAttach) {
            enclosureService.saveAttachment(attachment);
        }
        Object[] o = FileUploadUtil.reAttachment(sonAttach);
        DocumentModelWithBLOBs document = new DocumentModelWithBLOBs();
        if (1 == type) {//pdf为空  复制word
            document.setMainFile(o[0].toString().split(",")[0]);
            document.setMainFileName(o[1].toString().split("\\*")[0]);
        } else if (2 == type) {
            document.setMainAipFile(o[0].toString().split(",")[0]);
            document.setMainAipFileName(o[1].toString().split("\\*")[0]);
        }
        List<Attachment> attachmentList = null;
        if (2 == type) { //pdf不为空
            attachmentList = GetAttachmentListUtil.returnAttachment(document.getMainAipFileName(), document.getMainAipFile(), sqlType, module);
        } else if (1 == type) {
            attachmentList = GetAttachmentListUtil.returnAttachment(document.getMainFileName(), document.getMainFile(), sqlType, module);
        }

        json.setObj(attachmentList);
        json.setFlag(0);
        return json;
    }

    public ToJson<Attachment> flowAttachDocumentTitle(HttpServletRequest request, Integer runId) {
        ToJson<Attachment> json = new ToJson<>();
        //获取父公文实体类
        DocumentModel fathDocument = documentSerivce.checkRunId(runId);
        json.setObject(fathDocument.getTitle());
        json.setFlag(0);
        return json;
    }

    /**
     *
     * @param flowId
     * @return
     */
    public AjaxJson getAllDocument(Integer flowId) {
        AjaxJson ajaxJson = new AjaxJson();
        try {
            List<FlowFormType> forms = wfeFormTypeMapper.getFrombyFlowId(flowId);
            FlowFormType formType = forms.get(0);
            Map<String, Object> map = HtmlUtil.getAllDocument(formType.getPrintModel());
            ajaxJson.setFlag(true);
            ajaxJson.setObj(map);
        } catch (Exception e) {
            ajaxJson.setFlag(false);
            ajaxJson.setMsg(e.getMessage());
        }
        return ajaxJson;
    }
}
